	var nngBg={
		versionPattern:/^v(\d+)\.(\d+)\.(\d+)(\.(\d+)|[a-z].*|)$/i,
		runAtPattern:/^http(s):\/\/(bugtracker\.igomyway\.com|app\.nng\.com|codereview)/i,
		healthyKeyPattern:/^[0-9]+\.[a-z]+$/i,
		corruptedKeyPattern:/^undefined\.[a-z]+$/i,
		keyIsOurs:function(a){
			 if(typeof a!="string") throw new TypeError("Argument not a string.");
			 return Boolean(this.healthyKeyPattern.test(a)||this.corruptedKeyPattern.test(a))
		},
		deleteForeignPairs:function(){
			for(var a in localStorage)!this.keyIsOurs(a)&&localStorage.removeItem(a)&&console.log('foreign:'+a)
		},
		cleanStorage:function(){
			for(var a in localStorage) {
				this.corruptedKeyPattern.test(a)&&localStorage.removeItem(a)&&console.log('clean:'+a);
			}
		}
	};
	/*
	var v = 'v1.2.3.4';
	var m = nngBg.versionPattern.exec(v);
	if (m) {
		console.log('version:'+m[0]+'|'+m[1]+'|'+m[2]+'|'+m[3]+'|'+m[4]+'|')
	} else {
	}
	v = 'v1.2.3';
	m = nngBg.versionPattern.exec(v);
	if (m) {
		console.log('version:'+m[0]+'|'+m[1]+'|'+m[2]+'|'+m[3]+'|'+m[4]+'|')
	} else {
	}
	v = 'v1.2.3Pre';
	m = nngBg.versionPattern.exec(v);
	if (m) {
		console.log('version:'+m[0]+'|'+m[1]+'|'+m[2]+'|'+m[3]+'|'+m[4]+'|')
	} else {
	}
	*/
//	nngBg.deleteForeignPairs();
//	nngBg.cleanStorage();
	chrome.tabs.onUpdated.addListener(
		function(a,d,b){
			nngBg.runAtPattern.test(b.url) && 
			chrome.pageAction.show(a)
		}
	);
	chrome.extension.onRequest.addListener(
		function(a,d,b){
			if(a.action=="syncStorageUp"){
				for(var c in a.data=JSON.parse(a.data))
					localStorage.getItem(c)===null&&localStorage.setItem(c,a.data[c]);
				b()
			} else if (a.action=="syncStorageDown") {
				b(JSON.stringify(localStorage))			
			} else if (a.action=="getActive") {
				var ac = localStorage.getItem('activeMantis');
				if (ac != null) {
					b(ac);
				}
			} else if (a.action=="deleteFromStorage") {
				localStorage.removeItem(a.key);
			} else if (a.action=="setToStorage") {
				localStorage.setItem(a.key,a.value);
				console.log('setToStorage:'+a.key);
			} else if (a.action=="xhrGET") {
				$.get(a.url,function(a,c,d){
					b({xhrObject:JSON.stringify(d)})
				})
			} else if (a.action=="getVersion") {
				b(localStorage.getItem('nngVersion'));
			} else if (a.action=="getTTData") {
//				console.log('getTTData:'+localStorage.getItem('ttData'));
				b(localStorage.getItem('ttData'));
			} else if (a.action=="httpsTest") {
				$.get('https://www.test.naviextras.com/shopAdmin/',function(a,c,d){
					console.log(d);
					b(d)
				})
				
			} else if ( a.action=="tracked") {
				var tracked = [];
				var t = localStorage.getItem('tracked');
				console.log('tracked:'+(typeof localStorage.getItem('tracked'))+t);
				try {
					if ("string"==typeof t) {
						tracked = eval('('+localStorage.getItem('tracked')+')');
					}
				} catch (e) {
					console.log('tracked error:'+e);
				}
				if (tracked==null)  {
					tracked = [];
				}
				var newTracked = [{id:a.param.id,type:a.param.type}];
				for(var k in tracked) {
					if (tracked[k].id != a.param.id || 
						tracked[k].type != a.param.type) {
						newTracked.push(tracked[k]);
					}
				}
				console.log('tracked',$.toJSON(newTracked));
				localStorage.setItem('tracked',$.toJSON(newTracked));
				b(newTracked);
			} else if ( a.action=="grabProjects") {
				$.ajax( {
				  url: "https://app.nng.com/timetracker/Default.aspx",
				  type: 'POST',
				  dataType: 'html',
				  error : function (r, textStatus, errorThrown) {
					  console.log('error:'+textStatus+'|'+errorThrown+'|'+JSON.stringify(r));
					  b(textStatus, null);
				  },
				  success: function(data, textStatus, jqXHR){
					  console.log('success:'+data);
					  b('success', null);
				  }
				})
			} else if ( a.action=="postCRProject") {
				var param = a.param;
				$.ajax({
					type: 'POST',
					url: 'http://codereview/api/review-requests/'+param.mid+'/draft/',
					data: {api_format:'json', description: param.data},
					success:  function( data ) {
						b('Saved');
					},
					onerror:  function( data ) {
						b('Save failed');
					},
					dataType: 'json'
				});
			} else if ( a.action=="postMantisProject") {
				var param = a.param;
				$.ajax({
					type: 'POST',
					url: 'http://bugtracker.igomyway.com/bug_update_page.php',
					data: {bug_id: param.mid},
					success: function( data ) {
						var token = $( data ).find('input[name="bug_update_token"]' ).attr('value');
						console.log('token:'+token);
						$.ajax({
							type: 'POST',
							url: 'http://bugtracker.igomyway.com/bug_update.php',
							data: { 
								bug_update_token: token,
								bug_id : param.mid,
								update_mode : 1,
								custom_field_147: param.pname
							},
							success: function( data ) {
								console.log('postMantisProject success');
								b('Saved');
							},
							onerror: function( data ) {
								console.log('postMantisProject: Failed (2)');
								b('Save failed in stage 2');
							},
							dataType: 'html'
						});
					},
					onerror: function( ) {
						console.log('postMantisProject: Failed (1)');
						b('Save failed in stage 1');
					},
					dataType: 'html'
				});
			} else if ( a.action=="postJiraProject") {
				var param = a.param;
		        console.log('postJiraProject'+$.toJSON(a));
				$.ajax({
					type: 'POST',
					url: 'https://jira.nng.com/secure/IssueAction.jspa?decorator=none',
					data: { 
						customfield_10738: param.pname,
						issueId : param.issueId,
						atl_token: param.token,
						singleFieldEdit : true,
						fieldsToForcePresent: 'customfield_1073'
					},
					success: function( data ) {
						console.log('postJiraProject success');
						b('Saved');
					},
					onerror: function( data ) {
						console.log('postJiraProject: Failed (2)');
						b('Save failed in stage 2');
					},
					dataType: 'html'
				});
			} else {
				console.log('action:'+a.action);
			}
		}
	);
	
function getTTData() {
	$.ajax({
		type: 'POST',
		url: 'https://app.nng.com/timetracker/timetrackerservice.asmx',
		contentType: 'text/xml; charset="utf-8"',
		dataType: "xml",
		data : '<?xml version="1.0" encoding="utf-8"?>'
			+'<soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">'
			+'<soap12:Body>'
			+'<GetTaskInfoDataTable xmlns="http://app.nng.com/TimeTracker/" />'
			+'</soap12:Body>'
			+'</soap12:Envelope>',
		error:function( a, b, c ) {
			console.log('getProjects error:'+a+','+b+','+c);
		},
		success: function( data ) {
			console.log('getProjects :'+data);
			var tt = {customers:{}, projects:{}, tasks:{}};
			var pcount = 0;
			var tcount = 0;
			$(data).find('DocumentElement TaskInfo').each(function () {
				var cid = $(this).find('CustomerID').text();
				var pid = $(this).find('ProjectID').text();
				var tid = $(this).find('TaskID').text();
				if (tt.customers['c'+cid] == undefined) {
					tt.customers['c'+cid] = 
					{
						id : cid,
						name : $(this).find('CustomerName').text(),
						active: $(this).find('IsCustomerActive').text(),
						projects : []
					};
				}
				if (tt.projects['p'+pid] == undefined) {
					tt.projects['p'+pid] = 
					{
						id : pid,
						name: $(this).find('ProjectName').text(),
						active: $(this).find('IsProjectActive').text(),
						tasks: [],
						customer: cid,
						activeTasks: 0
					}
					pcount++;
				}
				if (tid!=0) {
					tt.tasks['t'+tid] = {
						id : tid,
						name : $(this).find('TaskName').text(),
						active: $(this).find('IsTaskActive').text(),
						project: pid
					}
					tt.projects['p'+pid].tasks.push(tid);
					tcount++;
					if ($(this).find('IsTaskActive').text()==="true") {
						tt.projects['p'+pid].activeTasks++;
					}
				} else {
					tt.customers['c'+cid].projects.push(pid);
				}
				
			});
			tt.write = (new Date()).getTime();
			console.log('pcount:'+pcount+', tcount:'+tcount);
			//console.log('getTTData data:'+$.toJSON(data));
			tt = sortTT(tt);
			//console.log('getTTData tt:'+$.toJSON(tt));
			localStorage.setItem('ttData',$.toJSON(tt));
		}
	})
}

function sortTT(tt) {
	tt.cidList = [];
	for(var k in tt.customers) {
		tt.cidList.push(k);
	}
	tt.cidList.sort(function(a,b) {
		var ap = tt.customers[a];
		var bp = tt.customers[b];
		return ap.name == bp.name ? 
			(ap.id == bp.id ? 0 : ap.id > bp.id ? -1 : 1)
		 : ap.name < bp.name ? -1 : 1  ;
	});
	for(var k in tt.customers) {
		tt.customers[k].projects.sort(function(a,b) {
			var ap = tt.projects['p'+a];
			var bp = tt.projects['p'+b];
			return ap.name == bp.name ? 
				(ap.id == bp.id ? 0 : ap.id > bp.id ? -1 : 1)
			 : ap.name < bp.name ? -1 : 1  ;
		});
	}
	tt.activeProjects = [];
	for(var k in tt.projects) {
		var p = tt.projects[k];
		if (p.active==="true"
			&&tt.customers['c'+p.customer]
			&&tt.customers['c'+p.customer].active==="true") {
			tt.activeProjects.push(k);
		}
	}
	tt.activeProjects.sort(function(a,b) {
		var ap = tt.projects[a];
		var bp = tt.projects[b];
		var an = getProjectName(a, tt).toUpperCase();
		var bn = getProjectName(b, tt).toUpperCase();
		return an == bn ? 
			(ap.id == bp.id ? 0 : ap.id > bp.id ? -1 : 1)
		 : an < bn ? -1 : 1  ;
	});
	/*
	for(var k in tt.activeProjects) {
		console.log('ap:'+getProjectName(tt.activeProjects[k],tt));
	}
	*/
	for(var k in tt.projects) {
		tt.projects[k].tasks.sort(function(a,b) {
			var ap = tt.tasks['t'+a];
			var bp = tt.tasks['t'+b];
			return ap.name == bp.name ? 
				(ap.id == bp.id ? 0 : ap.id > bp.id ? -1 : 1)
			 : ap.name < bp.name ? -1 : 1  ;
		});
	}
	return tt;
}

function  getProjectName(pid, ttData) {
	var result = pid +': Undefined';
	try {
		
		var p = ttData.projects[(typeof pid == "string" && pid.indexOf('p')==0)?pid:('p'+pid)];
		if (p) {
			var c = ttData.customers['c'+p.customer];
			result = (c?c.name:'-Unknown-')+'| '+p.name;
		}
	} catch (e) {
	}
	return result;
}

function getVersion() {
	console.log('getVersion');
	$.ajax({
		type: 'GET',
		url: 'http://nnghelper.googlecode.com/svn/trunk/version.json',
		error:function( a, b, c ) {
			console.log('setVersion error:'+a+','+b+','+c);
		},
		success: function( data ) {
			localStorage.setItem('nngVersion',data);
		},
		dataType: 'html'
	});
}
//console.log('getTTData start:'+localStorage.getItem('ttData'));
setInterval(getVersion, 600000);
getVersion();
setInterval(getTTData, 600000);
getTTData();
